﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.IO;
using System.Collections.Concurrent;
using System.Diagnostics;

namespace C0710_ChatRoom_Server
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            TextBox.CheckForIllegalCrossThreadCalls = false;    //关闭跨线程修改控件检查
        }

        Socket sokWatch = null;     //监听客户端连接请求
        Thread threadWatch = null;  //调用套接字执行监听请求的线程

        //开启监听按钮
        private void btnStartListen_Click(object sender, EventArgs e)
        {
            sokWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPAddress address = IPAddress.Parse(txtIP.Text.Trim());
            IPEndPoint endpoint = new IPEndPoint(address, int.Parse(txtPort.Text.Trim()));
            sokWatch.Bind(endpoint);
            sokWatch.Listen(10);    //设置监听队列长度为10(同时能够处理 10个连接请求)
            threadWatch = new Thread(StartWatch);
            threadWatch.IsBackground = true;
            threadWatch.Start();
            txtShow.AppendText("启动服务器成功......\r\n"+Process.GetCurrentProcess().Threads.Count);
            Log4NetInfo.Info("启动服务器成功......");
        }

        Dictionary<string, ConnectionClient> dictConn = new Dictionary<string, ConnectionClient>();
        ConcurrentDictionary<string, ConnectionClient> dictClient = new ConcurrentDictionary<string, ConnectionClient>();

        /// <summary>
        /// 被线程调用监听连接端口
        /// </summary>
        void StartWatch()
        {
            while (true)
            {
                //监听客户端连接请求,Accept会阻断当前线程
                Socket sokMsg = sokWatch.Accept();  //创建负责与该客户端套接字通信的套接字
                ConnectionClient connection = new ConnectionClient(sokMsg, dictConn, dictClient, ShowMsg, RemoveClientConnection);

                IPEndPoint clientipe = (IPEndPoint)sokMsg.RemoteEndPoint;
                //string ip = clientipe.Address.ToString();
                //var serverIP = System.Configuration.ConfigurationManager.AppSettings["serverIp"];
                ShowMsg(clientipe + " 接收连接成功......");
                Log4NetInfo.Info(clientipe + " 接收连接成功......");
            }
        }

        /// <summary>
        /// 移除与指定客户端的连接
        /// </summary>
        /// <param name="key">指定客户端的IP和端口</param>
        public void RemoveClientConnection(string key)
        {
            if (dictConn.ContainsKey(key))
            {
                ConnectionClient cc;
                dictConn.Remove(key);
            }
        }

        /// <summary>
        /// 向文本框显示消息
        /// </summary>
        /// <param name="msgStr">消息</param>
        public void ShowMsg(string msgStr)
        {
            txtShow.AppendText(DateTime.Now.ToString() + " " + msgStr + "\r\n");
        }
    }
}
